//
// Created by tacom on 2024/9/24.
//

#include "stdio.h"
#include "string.h"
#include "pico/stdlib.h"
#include "pico/binary_info.h"

#include "io_tools/io_helper.h"
#include "usb/dev_lowlevel.h"
#include "spi/spi_transfer.h"

//static bool send_spi_flag = false;
//static uint16_t send_len = 0;

// re-implement usb data_in, data_out
void ep1_out_handler(uint8_t *buf, uint16_t len) {
    // debug
    printf("Main: RX %d bytes from host\n", len);
    for(size_t i = 0; i < len; i++) printf("%x ", (unsigned int)(*(buf + i)));
    printf("\n");
    led_blink();

    // Send data to spi host
    if (len > 0){
        printf("Main: transfer start\n");
        // copy data to buf
        memcpy(out_buf, buf, len);
//        printf("Main: copy recv to spi buf\n");

        // drop down pin, ask host to receive data
        set_ask_pin_level(false);
        // busy_wait_us(100);
        // printf("Main: lowdown ask pin\n");

        // send data to spi
//        spi_slave_transfer_data(true, len);
        spi_slave_transfer_with_dma(true, len);
//        spi_loop_dma_test();
        // printf("Main: transfer spi buffer to host\n");
        set_ask_pin_level(true);
        printf("Main: transfer one done \n");
    }

    // Send data back to host
//    struct usb_endpoint_configuration *ep = usb_get_endpoint_configuration(EP2_IN_ADDR);
//    usb_start_transfer(ep, buf, len);
    usb_start_transfer(usb_get_endpoint_configuration(EP2_IN_ADDR), NULL, 64);
}

void ep2_in_handler(uint8_t *buf, uint16_t len) {
    // 此buffer可能来自: static uint8_t ep0_buf[64];
    // if(len > 0) printf("Main: Sent %d bytes to host, buf is: %s\n", len, (unsigned char *)buf);

    // Get ready to rx again from host
    usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64);
}


int main(void) {
    // enable stdio
    stdio_init_all();
    // usb
    usb_device_init();
    // spi
    spi_slave_init();
    // gpio
    helper_io_init();

    // Wait until configured
    printf("Main: Start to Wait Config\n");
    while (!configured) {
        tight_loop_contents();
    }

    // Get ready to rx from host
    usb_start_transfer(usb_get_endpoint_configuration(EP1_OUT_ADDR), NULL, 64);

    // Everything is interrupt driven so just loop here
    printf("Main: Start to loop event\n");
    while (1) {
        tight_loop_contents();
    }
}